package flexo.common;

/**
 * This class represents a generic system of the FLEXO engine.
 * Some examples are the Graphic System or the Scene System.
 * @author Miguel
 */
public abstract class System
{
	protected String name;
	protected float deltaTime;
	protected float accum;
	protected final boolean enableUpdate;
	
	public static final int UPDATE_MAX = 30;
	public static final int UPDATE_STANDARD = UPDATE_MAX;
	public static final int UPDATE_HALF = UPDATE_STANDARD / 2;
	public static final int UPDATE_NONE = 0;
	
	/**
	 * Creates the system and initializes it update ratio.
	 * @param name The name of the system. You should add it to a constant in your
	 * class so that other users can use that to retrieve the system from the Kernel.
	 * @param updateRate the update speed of the module. There are some predefined
	 * constants in this class, and it's recommended to use them.
	 */
	public System(String name, int updateRate)
	{
		flexo.Kernel.log("flexo.common.System", "Initializing '"+name+"' module");
		this.name = name;
		accum = 0;
		
		if (updateRate > 0)
		{
			// Limit to 60 fps
			if (updateRate > 60)
			{
				updateRate = 60;
			}
			this.deltaTime = 1.0f / updateRate;
			enableUpdate = true;
		}
		else
		{
			deltaTime = 0;
			enableUpdate = false;
		}
	}
	
	/**
	 * @return the name of the system.
	 */
	public String getName()
	{
		return name;
	}
	
	/**
	 * Override this method if you need to update your engine over time
	 * (your update rate shoud be bigger than zero).
	 */
	public void update(){}
	
	/**
	 * Called every frame to check if the system must be updated.
	 * @param elapsedTime elapsed time since last engine update, in seconds.
	 */
	public void tick(float elapsedTime)
	{
		if (enableUpdate)
		{
			accum += elapsedTime;
			
			if (accum >= deltaTime)
			{
				update();
				accum -= deltaTime;
			}
		}
	}
	
	/**
	 * @return update rate in seconds.
	 */
	public float getElapsedTime()
	{
		return deltaTime;
	}
	
	/**
	 * Deletes the system. If you override it (which is something common)
	 * remember to call this method through super.remove().
	 */
	public void remove()
	{
		flexo.Kernel.log("flexo.common.System", "Shutting down '"+name+"' module");
	}
	
	/**
	 * Returns the system's name.
	 */
	public String toString()
	{
		return name;
	}
}
